/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package herramientas;
import herramientas.notificar;

import beans.*;
import forms.LoginForm;
import forms.ProponerSuspensionForm;
import forms.RegistrarAsistenciaForm;
import java.sql.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.http.HttpSession;
/**
 *
 * @author javier
 */
public class baseDatos {
	private static int nroAbonados = 0;
    private static baseDatos instancia = null;
    private static final String url_bd = "jdbc:postgresql://localhost/deport_dide";
    private static Connection con;
    private static Statement state;

    private baseDatos() {
        try {
            Class.forName("org.postgresql.Driver");
            con = DriverManager.getConnection(url_bd, "deport_dide", "deportes");
            state = con.createStatement();
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(baseDatos.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SQLException se) {
            System.out.println("Couldn't connect: print out a stack trace and exit.");
            se.printStackTrace();
            System.exit(1);
        }
    }

    public synchronized static void cerrarConexion() {
        if (--nroAbonados == 0) {
            try {
                state.execute("END");
                state.close();
                con.close();
            } catch (Exception e) {
            }
            instancia = null;
        }
    }

    private synchronized static void crearInstancia() {
        if (instancia == null) {
            instancia = new baseDatos();
        }
    }

    public static baseDatos getInstance() {
        nroAbonados++;
        crearInstancia();
        return instancia;
    }

    public String loginUsuario(LoginForm lf) {
        try {
            String query = "select * from usuario where ci = "+lf.getLogin();
            System.out.println(query);
            ResultSet lista = state.executeQuery(query);
            if (lista.next()) {
                ResultSet listaD = state.executeQuery("select * from deportista where ci_deportista="+lf.getLogin());
                if (listaD.next())
                    return "deportista";
                listaD = state.executeQuery("select * from director where ci="+lf.getLogin());
                if (listaD.next())
                    return "director";
                listaD = state.executeQuery("select * from entrenador where ci_entrenador="+lf.getLogin());
                if (listaD.next())
                    return "entrenador";
            }
        } catch (SQLException ex) {
            Logger.getLogger(baseDatos.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }
    
    public ArrayList listarEntrenadores() {

        try {
            String query = "select * from entrenador natural join usuario order by nombres;";
            ResultSet lista = state.executeQuery(query);
            ArrayList entrenadores = new ArrayList();
            String entrenador, nombres, apellidos;
            while (lista.next()) {
                nombres = lista.getString("nombres");
		apellidos = lista.getString("apellidos");
		entrenador=nombres + " " + apellidos;
		entrenadores.add(entrenador);
            }
            return entrenadores;

        } catch (Exception e) {
            System.out.println(e.getMessage());
            return null;
        }
    }
    
  
     public ArrayList listarEntrenadores(String disciplina) {

        try {
            String query = "select nombres, apellidos, nombre, d.codigo from "
		    + "usuario u,entrenador e, disciplina_entrenador de, "
		    + "disciplina d where de.ci_entrenador = e.ci_entrenador "
		    + "and de.codigo = d.codigo and u.ci = e.ci_entrenador and"
		    + " nombre='"+disciplina+"';";
	    
            ResultSet lista = state.executeQuery(query);
            ArrayList entrenadores = new ArrayList();
            String entrenador, nombres, apellidos;
            while (lista.next()) {
                nombres = lista.getString("nombres");
		apellidos = lista.getString("apellidos");
		entrenador=nombres + " " + apellidos;
		entrenadores.add(entrenador);
            }
            return entrenadores;

        } catch (Exception e) {
            System.out.println(e.getMessage());
            return null;
        }
    }
     

     public ArrayList<DisciplinaTupla> listarDisciplinas(int ci_entrenador) {
        ArrayList<DisciplinaTupla> disciplinas = new ArrayList<DisciplinaTupla>();
        try {
            String query = "select * from disciplina d, disciplina_entrenador de "
                    + "where de.ci_entrenador = ? and d.codigo = de.codigo";
            PreparedStatement pstate = con.prepareStatement(query);
            pstate.setInt(1, ci_entrenador);
            ResultSet lista = pstate.executeQuery();
            System.out.println(pstate);
            while (lista.next()) {
		disciplinas.add(new DisciplinaTupla(lista.getString("codigo"), lista.getString("nombre")));
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
            
        }
        return disciplinas;
    }     
     
     public ArrayList<DisciplinaTupla> listarDisciplinas() {

        try {
            String query = "select * from disciplina;";
            ResultSet lista = state.executeQuery(query);
            ArrayList<DisciplinaTupla> disciplinas = new ArrayList<DisciplinaTupla>();
  
            while (lista.next()) {
		disciplinas.add(new DisciplinaTupla(lista.getString("codigo"), lista.getString("nombre")));
            }
            return disciplinas;

        } catch (Exception e) {
            System.out.println(e.getMessage());
            return null;
        }
    }

     public ArrayList<DeportistaTupla> listarDeportistas() {

        try {
            String query = "select * from usuario u, deportista d where u.ci = d.ci_deportista";
            ResultSet lista = state.executeQuery(query);
            ArrayList<DeportistaTupla> disciplinas = new ArrayList<DeportistaTupla>();
  
            while (lista.next()) {
		disciplinas.add(new DeportistaTupla(lista.getString("ci"),
                        lista.getString("nombres") + " "+ lista.getString("apellidos")));
            }
            return disciplinas;

        } catch (Exception e) {
            System.out.println(e.getMessage());
            return null;
        }
    }
     
    public ArrayList<DeportistaTupla> listarDeportistasPorDisciplina(String discid) {
        ArrayList<DeportistaTupla> disciplinas = new ArrayList<DeportistaTupla>();
        try {
            String query = "select * from usuario u, deportista d, disciplina_deportista dd "
                    + "where dd.codigo = ? and u.ci = d.ci_deportista and "
                    + "dd.ci_deportista = u.ci";
            PreparedStatement pstate = con.prepareStatement(query);
            pstate.setString(1, discid);
            ResultSet lista = pstate.executeQuery();
            
            while (lista.next()) {
		disciplinas.add(new DeportistaTupla(lista.getString("ci"),
                        lista.getString("nombres") + " "+ lista.getString("apellidos")));
            }

        } catch (Exception e) {
            System.out.println(e.getMessage());
            
        }
        return disciplinas;
    }
    
        
    public HorarioBean horarios(String discid) {
        try {
            String query = "select * from disciplina d, dias_entrenamiento de, "
                    + "horario h, disc_horario_dias wtf where "
                    + "wtf.codigo = d.codigo and "
                    + "wtf.cod_dias = de.cod_dias and "
                    + "wtf.cod_horario = h.cod_horario and "
                    + "d.codigo = ?";
            PreparedStatement pstate = con.prepareStatement(query);
            pstate.setString(1, discid);
            ResultSet lista = pstate.executeQuery();
            while (lista.next()) {
		return HorarioBean.from_resultset(lista);
            }

        } catch (Exception e) {
            System.out.println(e.getMessage());
            
        }        
        return null;
    }
    
     public ArrayList<PropuestaBean> listarPropuestasSuspension() {
        try {
            String query = "select u1.nombres AS nombres1, u1.apellidos AS apellidos1, "
                    + "u2.nombres AS nombres2, u2.apellidos AS apellidos2, s.id AS sid, s.*, m.* "
                    + "from suspendido s, motivo_suspension m, usuario u1, "
                    + "usuario u2 where s.ci_deportista = u1.ci and s.ci_entrenador = u2.ci "
                    + "and s.cod_motivo_suspension = m.cod_motivo_suspension "
                    + "and u1.ci = s.ci_deportista and not s.aprobado ";
            ResultSet lista = state.executeQuery(query);
            ArrayList<PropuestaBean> disciplinas = new ArrayList<PropuestaBean>();
  
            while (lista.next()) {
		disciplinas.add(new PropuestaBean(lista.getString("ci_deportista"),
                        lista.getString("ci_entrenador"),
                        lista.getString("descrip_motivo_suspension"), 
                        lista.getString("nombres2")+ " " + lista.getString("apellidos2"),
                        lista.getString("nombres1")+ " " + lista.getString("apellidos1"),                        
                        lista.getInt("sid")));
            }
            return disciplinas;

        } catch (Exception e) {
            System.out.println(e.getMessage());
            return null;
        }         
     }
     
     public void proponerSuspension(ProponerSuspensionForm psf, String ci_entrenador) {
         try {
            String query_suspendido = "insert into suspendido(ci_deportista, ci_entrenador, cod_motivo_suspension, "
                                    + "aprobado, fecha_propuesta) VALUES (?, ?, ?, ?, ?)";
            PreparedStatement pstate = con.prepareStatement(query_suspendido);
            pstate.setInt(1, Integer.parseInt(psf.getUsuario()));
            pstate.setInt(2, Integer.parseInt(ci_entrenador));
            pstate.setString(3, "aa");
            pstate.setBoolean(4, false);
            pstate.setDate(5, new Date((new java.util.Date()).getTime()));
            int affectedRows = pstate.executeUpdate();
            if (affectedRows == 0) {
                throw new SQLException("Creating failed, no rows affected.");
            }
        } catch (SQLException ex) {
            Logger.getLogger(baseDatos.class.getName()).log(Level.SEVERE, null, ex);
        }
         
     }
     
     public void registrarAsistencia(RegistrarAsistenciaForm raf) {
        try {
            SimpleDateFormat  sdf = new SimpleDateFormat("H:M"); 
            String query = "insert into asistencia (ci_deportista, fecha, hora_llegada, "
                    + "hora_salida, codigo) VALUES (?, ?, ?, ?, ?)";
            PreparedStatement pstate = con.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);
            pstate.setInt(1, Integer.parseInt(raf.getUsuario()));
            
            pstate.setDate(2, new java.sql.Date(raf.getFechaDate().getTime()));
            pstate.setTime(3, new java.sql.Time(sdf.parse(raf.getHoraEntrada()).getTime()));
            pstate.setTime(4, new java.sql.Time(sdf.parse(raf.getHoraSalida()).getTime()));
            pstate.setString(5, raf.getDisciplina());
            System.out.println(pstate);
            int affectedRows = pstate.executeUpdate();
            if (affectedRows == 0) {
                throw new SQLException("Creating failed, no rows affected.");
            }
        } catch (ParseException ex) {
            Logger.getLogger(baseDatos.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SQLException ex) {
            Logger.getLogger(baseDatos.class.getName()).log(Level.SEVERE, null, ex);
        }
        
     }
     
    
    public ArrayList detallesAsistencia(String ci) {

        try {
            String query = "select * from asistencia a , disciplina d, usuario "
		    + "u where ci_deportista='"+ci+"' and ci_deportista=u.ci "
		    + "and a.codigo= d.codigo;";
            ResultSet lista = state.executeQuery(query);
            ArrayList deportistas = new ArrayList();
            String fecha, hora_llegada, hora_salida;
            while (lista.next()) {
                fecha = lista.getString("fecha");
		hora_llegada = lista.getString("hora_llegada");
		hora_salida = lista.getString("hora_salida");
		String reporte[] = {fecha, hora_llegada, hora_salida};
		deportistas.add(reporte);
            }
            return deportistas;

        } catch (Exception e) {
            System.out.println(e.getMessage());
            return null;
        }

    }


    public void aprobarSuspension(int parseInt) {
        try {
            String query = "update suspendido set aprobado = true where id = ?";
            PreparedStatement pstate = con.prepareStatement(query);
            pstate.setInt(1, parseInt);
            pstate.executeQuery();
            /* TODO: Notificar por email */
        } catch (SQLException ex) {
            Logger.getLogger(baseDatos.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
        
    public ArrayList<DeportistaTupla> listarDeportistasEnFalta() {
        ArrayList<DeportistaTupla> deportistas = new ArrayList<DeportistaTupla>();
        try {
            String query = "select distinct u.nombres, u.apellidos, u.ci "
                    + "from deportista d, suspendido s, usuario u "
                    + "where d.ci_deportista = s.ci_deportista "
                    + "and u.ci = d.ci_deportista "
                    + "and s.cod_motivo_suspension = 'aa' "
                    + "and s.aprobado";
            ResultSet lista = state.executeQuery(query);
  
            while (lista.next()) {
		deportistas.add(new DeportistaTupla(lista.getString("nombres")
                        +" "+lista.getString("apellidos"),
                        lista.getString("ci")));
            }
            return deportistas;

        } catch (Exception e) {
            System.out.println(e.getMessage());
            
        }
        return deportistas;
    }
    
    public ArrayList<DeportistaTupla> listarDeportistas(String disciplina) {     
        try {
            String query = "select * from usuario u, deportista d, disciplina_deportista de, disciplina dis where u.ci = d.ci_deportista and de.ci_deportista=u.ci and dis.codigo=de.codigo and dis.nombre='"+disciplina+"';";
            ResultSet lista = state.executeQuery(query);
            ArrayList<DeportistaTupla> disciplinas = new ArrayList<DeportistaTupla>();
  
            while (lista.next()) {
		disciplinas.add(new DeportistaTupla(lista.getString("ci"),
                        lista.getString("nombres") + " "+ lista.getString("apellidos")));
            }
            return disciplinas;

        } catch (Exception e) {
            System.out.println(e.getMessage());
            return null;
        }
    }

    public ArrayList<String> deportistaSuspendido(String sus_id) {

        try {
            String query = "select u.usbid from usuario u, suspendido s"
                    + "where u.ci = s.ci_deportista and s.id = "+sus_id+";";
            ResultSet lista = state.executeQuery(query);
            ArrayList<String> deportista = new ArrayList<String>();
  
            while (lista.next()) {
		deportista.add(lista.getString(sus_id));
            }
            return deportista;
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return null;
        }
    }
    public ArrayList<ArrayList<AsistenciaBean>> listarAsistencias(String disciplina) {
        ArrayList<ArrayList<AsistenciaBean>> returnable = new ArrayList<ArrayList<AsistenciaBean>>();
        try {
            String query = "select * from asistencia a, usuario u where a.codigo = ? "
                    + "and a.ci_deportista = u.ci "
                    + "order by fecha desc";
            
            PreparedStatement pstate = con.prepareStatement(query);
            
            pstate.setString(1, disciplina);
            System.out.println(pstate);
            ResultSet lista = pstate.executeQuery();
            AsistenciaBean prev = null;
            ArrayList<AsistenciaBean> nueva = new ArrayList<AsistenciaBean>();
            System.out.println(lista);
            System.out.println("ANTES DE AGREGAR");
            if (lista.next()) {
                prev = AsistenciaBean.from_resultset(lista);
                nueva.add(prev);
                System.out.println(prev);
            }
            while (lista.next()) {
                AsistenciaBean current = AsistenciaBean.from_resultset(lista);
                if (current.equals(prev)) {
                    System.out.println("Aqui");
                    nueva.add(current);
                } else {
                    returnable.add(nueva);
                    nueva = new ArrayList<AsistenciaBean>();
                    nueva.add(current);
                }
                prev = current;
            }
            if (nueva.size() > 0)
                returnable.add(nueva);
        } catch (SQLException ex) {
            System.out.println(ex.getMessage());
            
        }
        return returnable;
        
    }

}
